// LemCoop
// Copyright (C) 2013  Oliver Naumann <bldrax@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "animation.h"

Animation::Animation(std::string bitmap, unsigned size_x, unsigned size_y, unsigned bitmap_x,
		unsigned bitmap_y, unsigned number_of_elements, float time)
{
	m_bitmap = bitmap;
	m_size_x = size_x;
	m_size_y = size_y;
	m_bitmap_x = bitmap_x;
	m_bitmap_y = bitmap_y;
	m_number_of_elements = number_of_elements;

	m_current_ticks = 0.0f;
	m_current_element = 0;
	m_time.push_back(time);

	m_animation_ended = false;
}

void Animation::AddTime(float time)
{
	m_time.push_back(time);
}

void Animation::Reset()
{
	m_current_ticks = 0.0f;
	m_current_element = 0;
}

void Animation::Update(float timing_factor)
{
	// TODO: This does not have to be done if there is only one element.
		
	m_current_ticks += timing_factor;

	float time;
	m_animation_ended = false;

	// If there is no time stored, just switch the element every hundreths second
	if (m_time.size() == 0)
		time = 1.0;
	// If there is no time stored for current_element, use standard time m_time[0].
	else if (m_current_element >= m_time.size())
		time = m_time.at(0);
	// If there is a time value for the current element, use it.
	else
		time = m_time.at(m_current_element);

	// Is it time for the next element to be shown?
	while (m_current_ticks >= time)
	{
		m_current_ticks -= time;
		m_current_element++;

		if (m_current_element >= m_number_of_elements)
		{
			m_current_element = 0;
			m_animation_ended = true;
		}
	}
}

bool Animation::GetXYFromCurrentElementNumber(int &x, int &y)
{
	// Retrieve image information
	ALLEGRO_BITMAP* bitmap = allegro_bitmap_resource_manager.GetResource(m_bitmap);
	int bitmap_size_x = al_get_bitmap_width(bitmap);
	int bitmap_size_y = al_get_bitmap_height(bitmap);

	// Set x,y
	x = m_bitmap_x + m_size_x * m_current_element;
	y = m_bitmap_y;

	if (x + m_size_x > bitmap_size_x || y + m_size_y > bitmap_size_y || x < 0 || y < 0)
	{
		LogManager::LogLine("Error when trying to get xy-coordinates for animation from bitmap '" + m_bitmap +
			"'. Out of bounds of source bitmap.");
		return false;
	}

	return true;
}

void Animation::Draw(int x, int y, float scale_x, float scale_y, float opacity)
{
	// Does it have to be drawn at all?
	if (x <= Screen::GetInstance()->width() && y <= Screen::GetInstance()->height()
		&& x + m_size_x * scale_x >= 0 && y + m_size_y * scale_y >= 0)
	{
		int source_x;
		int source_y;

		GetXYFromCurrentElementNumber(source_x, source_y);

		al_draw_tinted_scaled_rotated_bitmap_region(allegro_bitmap_resource_manager.GetResource(m_bitmap), source_x, source_y, m_size_x, m_size_y,
			al_map_rgba_f(1.0 * opacity, 1.0 * opacity, 1.0 * opacity, opacity), 0, 0, x, y, scale_x, scale_y, 0, NULL);
	}
}